package com.jiguang.property.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jiguang.property.dto.NoticeInfoDTO;
import com.jiguang.property.dto.ParkInfoDTO;
import com.jiguang.property.dto.UpkeepInfoDTO;
import com.jiguang.property.dto.UserInfoDTO;
import com.jiguang.property.entity.ParkInfo;
import com.jiguang.property.entity.UpkeepInfo;
import com.jiguang.property.entity.User;
import com.jiguang.property.handler.GlobalExceptionHandel;
import com.jiguang.property.handler.GuliException;
import com.jiguang.property.mapper.UpkeepInfoMapper;
import com.jiguang.property.service.UpkeepInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jiguang.property.service.UserService;
import com.jiguang.property.utils.JwtUtils;
import com.jiguang.property.utils.Result;
import io.netty.util.internal.StringUtil;
import lombok.SneakyThrows;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author testjava
 * @since 2025-03-24
 */
@Service
public class UpkeepInfoServiceImpl extends ServiceImpl<UpkeepInfoMapper, UpkeepInfo> implements UpkeepInfoService {
    @Autowired
    private UserService userService;
    @Autowired
    private JwtUtils tokenManager;
    @Autowired
    private RedisTemplate redisTemplate;


    @SneakyThrows
    @Override
    public Result listUpkeepInfo(UpkeepInfoDTO upkeepInfoDTO) {
        //通过工具类获取Request对象
        ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = sra.getRequest();
        //获取用户名
        //需要通过解析token获取
        String token = request.getHeader("token");
        if (StringUtils.isEmpty(token)){
            return Result.error().code(403).message("登陆超时，请重新登陆");
        }
        String userId = tokenManager.getUserFromToken(token);

        //从redis中获取用户信息
        String redisKey = "login:" + userId;
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        String cacheObject = (String) redisTemplate.opsForValue().get(redisKey);
        if (StringUtils.isEmpty(cacheObject)) {
            return Result.error().code(403).message("登陆超时，请重新登陆");
        }
        UserInfoDTO ucenter = new ObjectMapper().readValue(cacheObject.toString(), UserInfoDTO.class);

        //判断用户的权限
        if (ucenter.getPosition() != null && (ucenter.getPosition() == 2 || ucenter.getPosition() == 1)){
            userId = null;
        }

        List<UpkeepInfoDTO> upkeepInfoDTOS = baseMapper.listByCriteria(upkeepInfoDTO,userId);

        //获取列表总数
        Integer totelByCriteria = baseMapper.getTotelByCriteria(upkeepInfoDTO,userId);

        return Result.ok().message("查询成功").data("upkeepInfos", upkeepInfoDTOS).data("total",totelByCriteria);
    }

    @Override
    public Result deleteUpkeepInfo(String upkeepIds) {
        if (StringUtils.isEmpty(upkeepIds)) return Result.error().message("Id不能为空");
        List<String> ids = Arrays.asList(upkeepIds.split(","));
        baseMapper.deleteBatchIds(ids);
        return Result.ok().message("删除成功");
    }

    @Override
    public Result updateOrAddUpkeepInfo(UpkeepInfoDTO upkeepInfoDTO) {
        UpkeepInfo upkeepInfo = new UpkeepInfo();
        BeanUtils.copyProperties(upkeepInfoDTO,upkeepInfo);

        if (StringUtil.isNullOrEmpty(upkeepInfo.getId())){
            upkeepInfo.setStatus(1);
            if (StringUtils.isEmpty(upkeepInfo.getPrebookEndTime())){
                return Result.error().message("预约时间不能为空");
            }

            if (upkeepInfoDTO.getStatus() == 0 && StringUtils.isEmpty(upkeepInfoDTO.getReporterId())){
                return Result.error().message("上报人不能为空");
            }

            boolean b = existPark(upkeepInfoDTO);
            if (b) {return Result.error().message("存在相关上报");}

            //分配维修人员
            allocationUp(upkeepInfo);

            baseMapper.insert(upkeepInfo);
        }else{
            boolean b = existPark(upkeepInfoDTO);
            if (b) {return Result.error().message("存在相关上报");}
            baseMapper.updateById(upkeepInfo);
        }
        return Result.ok().message("成功");
    }

    @SneakyThrows
    @Override
    public Result getUpkeepNumber() {
        //通过工具类获取Request对象
        ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = sra.getRequest();
        //获取用户名
        //需要通过解析token获取
        String token = request.getHeader("token");
        if (StringUtils.isEmpty(token)){
            return Result.error().code(403).message("登陆超时，请重新登陆");
        }
        String userId = tokenManager.getUserFromToken(token);

        //从redis中获取用户信息
        String redisKey = "login:" + userId;
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        String cacheObject = (String) redisTemplate.opsForValue().get(redisKey);
        if (StringUtils.isEmpty(cacheObject)) {
            return Result.error().code(403).message("登陆超时，请重新登陆");
        }
        UserInfoDTO ucenter = new ObjectMapper().readValue(cacheObject.toString(), UserInfoDTO.class);

        QueryWrapper<UpkeepInfo> upWrapper = new QueryWrapper<>();
        upWrapper.eq("is_delete",0);
        if(ucenter.getPosition() == 4){
            return Result.ok().data("upkeepNumber",0).data("waitSolve",0);
        }else if(ucenter.getPosition() == 3){
            upWrapper.eq("upkeep_id",userId);
            Integer upkeepNumber = baseMapper.selectCount(upWrapper);
            upWrapper.eq("status",1);
            Integer waitSolve = baseMapper.selectCount(upWrapper);
            return Result.ok().data("upkeepNumber",upkeepNumber).data("waitSolve",waitSolve);
        }else if(ucenter.getPosition() == 1 || ucenter.getPosition() == 2){
            Integer upkeepNumber = baseMapper.selectCount(upWrapper);
            upWrapper.ne("status",3).ne("status",4);
            Integer waitSolve = baseMapper.selectCount(upWrapper);
            return Result.ok().data("upkeepNumber",upkeepNumber).data("waitSolve",waitSolve);
        }else if(ucenter.getPosition() == 0){
            upWrapper.eq("reporter_id",userId);
            Integer upkeepNumber = baseMapper.selectCount(upWrapper);
            upWrapper.ne("status",3).ne("status",4);
            Integer waitSolve = baseMapper.selectCount(upWrapper);
            return Result.ok().data("upkeepNumber",upkeepNumber).data("waitSolve",waitSolve);
        }
        return Result.ok().data("upkeepNumber",0).data("waitSolve",0);
    }

    /**
     * 判断是否存在相同维修上报
     */
    private boolean existPark(UpkeepInfoDTO upkeepInfoDTO){
        QueryWrapper<UpkeepInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("reporter_id",upkeepInfoDTO.getReporterId());
        wrapper.eq("hostel_id",upkeepInfoDTO.getHostelId());
        wrapper.ne("status",3).ne("status",4);
        UpkeepInfo upkeepInfo = baseMapper.selectOne(wrapper);

        if (upkeepInfo != null){
            if (!StringUtils.isEmpty(upkeepInfo.getId()) && !upkeepInfo.getId().equals(upkeepInfoDTO.getId())){
                return true;
            }else if (StringUtils.isEmpty(upkeepInfoDTO.getId())){
                return true;
            }else{
                return false;
            }
        }
        return false;
    }

    /**
     * 分配维修人员
     */
    private void allocationUp(UpkeepInfo upkeepInfo){
        //查询维修人员
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("position",3);
        wrapper.eq("is_delete",0);
        List<User> userList = userService.list(wrapper);

        if (CollectionUtils.isEmpty(userList)) throw new GuliException(11001, "抱歉，该时间段预约数量已满");

        for (User user : userList) {
            //查询预约时间没维修任务的人员
            QueryWrapper<UpkeepInfo> upWrapper = new QueryWrapper<>();
            upWrapper.eq("upkeep_id",user.getId());
            upWrapper.eq("status",1);
            upWrapper.eq("prebook_end_time",upkeepInfo.getPrebookEndTime());
            UpkeepInfo upkeepInfoByUser = baseMapper.selectOne(upWrapper);

            if (upkeepInfoByUser == null){
                upkeepInfo.setUpkeepId(user.getId());
                break;
            }
        }

        if (StringUtils.isEmpty(upkeepInfo.getUpkeepId())){
            throw new GuliException(11001, "抱歉，该时间段预约数量已满");
        }
    }
}
